local tokens_key = KEYS[1]
local timestamp_key = KEYS[2]
--redis.log(redis.LOG_WARNING, "tokens_key " .. tokens_key)
-- 参数1：速率
local rate = tonumber(ARGV[1])
-- 参数2：容量
local capacity = tonumber(ARGV[2])
--参数3：当前时间戳
local now = tonumber(ARGV[3])
--参数4：当前需要的令牌数量
local requested = tonumber(ARGV[4])
--填充时间=容量除以/速率
local fill_time = capacity/rate
--keys过期时间
local ttl = math.floor(fill_time*2)

-- 如果令牌为空，则填充当前容量
local last_tokens = tonumber(redis.call("get", tokens_key))
if last_tokens == nil then
  last_tokens = capacity
end

--获取当前令牌时间戳，如果为nil，则设置为0
local last_refreshed = tonumber(redis.call("get", timestamp_key))
if last_refreshed == nil then
  last_refreshed = 0
end

-- 当前时间戳和令牌最后刷新时间差值，和0比较，取最大值
local delta = math.max(0, now-last_refreshed)
--最后的令牌桶数量+当前填入数量（时间差*请求速率），和capacity比较取最小值，就是比较是不是快满了
local filled_tokens = math.min(capacity, last_tokens+(delta*rate))
--如果当前令牌桶没有满，则将令牌桶数量减1，说明当前可以继续请求，不丢弃
local allowed = filled_tokens >= requested
local new_tokens = filled_tokens
local allowed_num = 0
if allowed then
  new_tokens = filled_tokens - requested
  allowed_num = 1
end
-- 更新令牌桶当前容量和最新时间
redis.call("setex", tokens_key, ttl, new_tokens)
redis.call("setex", timestamp_key, ttl, now)

return { allowed_num, new_tokens }